package com.handydata.antifraud.channel;

import java.util.HashMap;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.handydata.antifraud.bo.orderbaseinfo.OrderBaseInfoReqBO;
import com.handydata.antifraud.bo.orderbaseinfo.OrderBaseInfoResBO;
import com.handydata.antifraud.service.OrderBaseInfoService;
import com.handydata.common.convert.CommonBeanConvertor;

@Slf4j
@Component
public class RabbitSender {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;
    private OrderBaseInfoService service;
    //回调函数: confirm确认
    final RabbitTemplate.ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {
        @Override
        public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            log.info("correlationData: " + correlationData);//从数据库捞出来补偿
            log.info("ack: " + ack);
            if(!ack){
                long count=redisTemplate.opsForValue().increment("send_fail_"+correlationData.getId(),1);
                if(count>3) return;
                log.info("-------------发送消息异常....，开始从数据库重发--------------------");
                OrderBaseInfoReqBO reqBO=new OrderBaseInfoReqBO();
                reqBO.setOrderId(correlationData.getId());
                OrderBaseInfoResBO resBO= service.queryOrderBaseInfo(reqBO);
                if(resBO!=null&&resBO.getResultList().size()>0){
                    OrderBaseInfoReqBO newReq=CommonBeanConvertor.convert(resBO.getResultList().get(0),reqBO.getClass());
                    try {
                        send(JSON.toJSONString(newReq),correlationData.getId());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    };

    //回调函数: return返回
    final RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {//先不处理
        @Override
        public void returnedMessage(org.springframework.amqp.core.Message message, int replyCode,
                                    String replyText, String exchange, String routingKey) {
            log.info("return exchange: {}, routingKey: {}, replyCode: {}, replyText: {}",
                    exchange, routingKey, replyCode, replyText);
        }
    };

    //发送消息方法调用: 构建Message消息
    public void send(Object message,String id) throws Exception {
        Map<String, Object> properties=new HashMap<String, Object>();
        MessageHeaders mhs = new MessageHeaders(properties);
        Message<Object> msg = MessageBuilder.createMessage(message,mhs);
        rabbitTemplate.setConfirmCallback(confirmCallback);
        rabbitTemplate.setReturnCallback(returnCallback);
        //rabbitTemplate.setChannelTransacted(true);//开启事务
        //id + 时间戳 全局唯一
        //String id = UUID.randomUUID().toString();
        log.info("===============接收订单号orderID{}", id);
        CorrelationData correlationData = new CorrelationData(id);
        rabbitTemplate.convertAndSend("exchange-2", "springboot.abc", msg, correlationData);
    }
}